import axios, { AxiosRequestConfig, AxiosResponse } from 'axios'
import Logger from '../log'
import { getUrlParams, isMeetingCore } from '@/utils'
import { SYSTEM_VERSION, API_MEETING_PREFIX, API_PROTAL_PREFIX } from '@/utils/constant'
import Alert from '@/components/Alert'
import { t } from 'i18next'
import { updateDescription } from './errorCode'

function _getWsM() {
	let reg = new RegExp('(^|&)_ws_m=([^&]*)(&|$)') //构造一个含有目标参数的正则表达式对象
	let r = window.location.search.substring(1).match(reg) //匹配目标参数
	if (r != null) return decodeURI(r[2])
	return null //返回参数值
}

function handleErrorCode(response: AxiosResponse<any>) {
	const { data } = response
	if (
		data &&
		((data.errorCode &&
			(data.errorCode === 100013 ||
				data.errorCode === 100012 ||
				data.errorCode === 100011 ||
				data.errorCode === 100010)) ||
			(data.error_code &&
				(data.error_code === 100013 ||
					data.error_code === 100012 ||
					data.error_code === 100011 ||
					data.error_code === 100010)))
	) {
		window.location.href = window.location.origin + '/portal/login'
		return 'error'
	}

	if (data && ((data.errorCode && data.errorCode === 200001) || (data.error_code && data.error_code === 200001))) {
		let url = isMeetingCore() ? '/meetingCore' : '/meeting'
		window.location.href = `${window.location.origin}${url}/no_permission.html`

		return 'error'
	}
}

function setToken(fn: (token: string) => void) {
	if (window.KDV_BP_KEY) {
		fn(window.KDV_BP_KEY)
	} else {
		const script = document.createElement('script')
		script.src = `${API_PROTAL_PREFIX}/kdv/biz/bp.min.js?t=${new Date().getTime()}`
		script.onload = function () {
			fn(window.KDV_BP_KEY)
		}
		//@ts-ignore  ie才会使用
		script.onreadystatechange = function () {
			//@ts-ignore
			if (script.readyState === 'loaded' || script.readyState === 'complete') {
				fn(window.KDV_BP_KEY)
			}
		}
		document.getElementsByTagName('head')[0].appendChild(script)
	}
}

function setRequestLog(config: AxiosRequestConfig<any>) {
	try {
		Logger.add({
			info: {
				url: config.url,
				data: decodeURI(config.data),
				params: decodeURI(JSON.stringify(config.params)?.replace(/%/g, '%25')),
				type: config.method?.toUpperCase(),
			},
			type: `request-${config.method?.toUpperCase() || 'UNKNOW'}`,
		})
	} catch (e) {
		Logger.add({
			info: {
				url: config.url,
				type: config.method?.toUpperCase(),
			},
			type: `request-${config.method?.toUpperCase() || 'UNKNOW'}-catch-error`,
		})
	}
}
function setResponseLog(response: AxiosResponse<any, any>) {
	Logger.add({
		info: {
			url: response.config.url,
			data: response.request.responseText,
			type: response.config.method?.toUpperCase(),
			status: response.status,
		},
		type: `response-${response.config.method?.toUpperCase() || 'UNKNOW'}`,
	})
}

function canSetHeaderMoAction(config: AxiosRequestConfig<any>) {
	const isMcc = window.location.pathname.indexOf('/manager.html') > -1
	const apiList = ['/web/messages', '/open_url', '/api/inner/ops/diagnose']
	let flag = false
	for (let i = 0; i < apiList.length; i++) {
		const url = apiList[i]
		if (`${config.baseURL}${config.url}`?.includes(url)) {
			flag = true
		}
	}
	if (isMcc || flag) {
		return true
	}
	return false
}

const fetchAxios = axios.create({
	baseURL: API_MEETING_PREFIX,
	timeout: 115000,
	headers: {
		'Content-Type': 'application/json',
		'X-Requested-With': 'XMLHttpRequest',
		'Mo-Source': 'meeting',
		'Mo-Version': SYSTEM_VERSION,
	},
})

//请求拦截
fetchAxios.interceptors.request.use(
	(config) => {
		config.headers = config.headers || {}

		if (_getWsM()) (config.headers as any)['AGW-ROOM-ID'] = _getWsM()

		if (canSetHeaderMoAction(config)) {
			;(config.headers as any)['Mo-Action'] = 'AUTO'
		}

		if (config.method === 'delete') {
			//兼容智林
			config.method = 'post'
			if (config.url?.includes('?')) {
				config.url = config.url + '&_method=DELETE'
			} else {
				config.url = config.url + '?_method=DELETE'
			}
		}

		if (config.method === 'post' || config.method === 'delete' || config.method === 'put') {
			return new Promise(function (resolve) {
				setToken((KDV_BP_KEY) => {
					;(config.headers as any)['X-CSRF-TOKEN'] = KDV_BP_KEY
					setRequestLog(config)
					resolve(config)
				})
			})
		}
		setRequestLog(config)
		return config
	},
	(error) => {
		return Promise.reject(error)
	}
)

//返回拦截
fetchAxios.interceptors.response.use(
	(response) => {
		setResponseLog(response)
		//特殊处理share.html的skyforweb跳转
		if ((response.config as any)?.__special__ === 'share') {
			return Promise.reject(response)
		}

		if (handleErrorCode(response) === 'error') {
			return Promise.reject('error: go login page by errorCode')
		}

		if (response.status !== 200) {
			return response.data
			// return Promise.reject('error: response status is not 200')
		} else {
			updateDescription(response.data)
			return response.data
		}
	},
	(error) => {
		if (error && error.response) {
			//特殊处理share.html的skyforweb跳转
			if ((error.response.config as any)?.__special__ === 'share') {
				return Promise.reject(error.response)
			}
			if (
				error.response.status === 403 &&
				error.response.headers &&
				error.response.headers['request-sso-token'] !== window.REQUEST_SSO_TOKEN
			) {
				Alert(t('用户信息发生变化，部分功能受限，请重新刷新页面尝试'), () => {
					window.document.location.reload()
				})
			} else {
				handleErrorCode(error.response)
			}
		}
		return Promise.reject(error)
	}
)

const requestMeeting = <T>(reqConfig: AxiosRequestConfig): Promise<FetchRes<T>> => {
	return fetchAxios.request<FetchRes<T>, FetchRes<T>>(reqConfig)
}

export const request = <T>(reqConfig: AxiosRequestConfig): Promise<FetchUse<T>> => {
	return fetchAxios.request<FetchUse<T>, FetchUse<T>>(reqConfig)
}

export default requestMeeting
export { fetchAxios }
